<template>
  <div class="announcements-container">
    <div class="header">
      <h1>系统公告</h1>
      <div class="search-box">
        <el-input
          v-model="searchQuery"
          placeholder="搜索公告..."
          :prefix-icon="Search"
          clearable
          @clear="handleSearch"
          @input="handleSearch"
        />
      </div>
    </div>

    <div class="announcements-content">
      <div v-if="loading" class="loading-container">
        <el-skeleton :rows="5" animated />
      </div>
      
      <div v-else-if="announcements.length === 0" class="empty-container">
        <el-empty description="暂无公告" />
      </div>
      
      <div v-else class="announcements-list">
        <el-timeline>
          <el-timeline-item
            v-for="item in announcements"
            :key="item.id"
            :timestamp="formatDate(item.createdTime)"
            placement="top"
            :color="getRandomColor(item.id)"
          >
            <el-card class="announcement-card" @click="showAnnouncementDetail(item)">
              <template #header>
                <div class="card-header">
                  <h3>{{ item.title }}</h3>
                </div>
              </template>
              <div class="preview-content">
                {{ getContentPreview(item.content) }}
              </div>
            </el-card>
          </el-timeline-item>
        </el-timeline>
        
        <div class="pagination-container">
          <el-pagination
            :current-page="currentPage"
            :page-size="pageSize"
            :page-sizes="[5, 10, 20, 50]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            @update:current-page="currentPage = $event"
            @update:page-size="pageSize = $event"
          />
        </div>
      </div>
    </div>

    <!-- 公告详情对话框 -->
    <el-dialog
      v-model="detailDialogVisible"
      :title="currentAnnouncement.title"
      width="700px"
    >
      <div class="announcement-meta">
        <span class="date">发布日期: {{ formatDate(currentAnnouncement.createdTime) }}</span>
        <span v-if="currentAnnouncement.updatedTime && currentAnnouncement.updatedTime !== currentAnnouncement.createdTime" 
              class="date">
          更新日期: {{ formatDate(currentAnnouncement.updatedTime) }}
        </span>
      </div>
      <div v-if="currentAnnouncement.content" v-html="formatContent(currentAnnouncement.content)" class="announcement-detail-content"></div>
      <div v-else class="empty-content">暂无详细内容</div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { Search } from '@element-plus/icons-vue'
import request from '@/utils/request'

// 状态变量
const loading = ref(false)
const announcements = ref([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
const searchQuery = ref('')
const detailDialogVisible = ref(false)
const currentAnnouncement = ref({})

// 颜色列表
const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399']

// 防抖函数
const debounce = (fn, delay) => {
  let timer = null
  return (...args) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

// 获取公告列表
const fetchAnnouncements = async () => {
  loading.value = true
  try {
    const params = {
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      search: searchQuery.value
    }
    
    await request.get('/announcement/page', params, {
      showDefaultMsg: false,
      onSuccess: (res) => {
        announcements.value = res.records||[]
        total.value = res.total||0
      }
    })
  } catch (error) {
    console.error('获取公告列表失败:', error)
  } finally {
    loading.value = false
  }
}

// 处理分页
const handleSizeChange = (val) => {
  pageSize.value = val
  fetchAnnouncements()
}

const handleCurrentChange = (val) => {
  currentPage.value = val
  fetchAnnouncements()
}

// 处理搜索
const handleSearch = debounce(() => {
  currentPage.value = 1
  fetchAnnouncements()
}, 300)

// 显示公告详情
const showAnnouncementDetail = (announcement) => {
  currentAnnouncement.value = announcement
  detailDialogVisible.value = true
}

// 获取内容预览
const getContentPreview = (content) => {
  if (!content) return '暂无详细内容...'
  return content.length > 100 ? content.substring(0, 100) + '...' : content
}

// 获取随机颜色
const getRandomColor = (id) => {
  return colors[id % colors.length]
}

// 格式化内容 (将换行符转换为<br>)
const formatContent = (content) => {
  if (!content) return ''
  return content.replace(/\n/g, '<br>')
}

// 格式化日期
const formatDate = (date) => {
  if (!date) return ''
  const d = new Date(date)
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
}

// 初始化
onMounted(() => {
  fetchAnnouncements()
})
</script>

<style lang="scss" scoped>
.announcements-container {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
  
  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    flex-wrap: wrap;
    gap: 20px;
    
    h1 {
      margin: 0;
      font-size: 28px;
      color: var(--el-color-primary);
    }
    
    .search-box {
      width: 300px;
    }
  }
  
  .announcements-content {
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    padding: 20px;
    
    .loading-container, .empty-container {
      padding: 30px 0;
    }
    
    .announcements-list {
      .announcement-card {
        cursor: pointer;
        transition: transform 0.3s;
        
        &:hover {
          transform: translateY(-5px);
          box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
        }
        
        .card-header {
          h3 {
            margin: 0;
            font-size: 18px;
            color: var(--el-color-primary);
          }
        }
        
        .preview-content {
          color: var(--el-text-color-regular);
          font-size: 14px;
          line-height: 1.6;
          white-space: pre-line;
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }
    }
    
    .pagination-container {
      display: flex;
      justify-content: center;
      margin-top: 30px;
    }
  }
}

.announcement-meta {
  margin-bottom: 20px;
  color: var(--el-text-color-secondary);
  font-size: 14px;
  
  .date {
    margin-right: 20px;
  }
}

.announcement-detail-content {
  line-height: 1.8;
  color: var(--el-text-color-primary);
  white-space: pre-line;
  
  :deep(p) {
    margin: 8px 0;
  }
}

.empty-content {
  color: var(--el-text-color-secondary);
  font-style: italic;
  text-align: center;
  padding: 30px 0;
}
</style> 